package org.smart4j.framework.common.aop;

import lombok.Data;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.util.List;

/**
 * 代理链
 *
 * @author YooLin1c
 * @version 1.0.0
 * @since 2018-02-03 13:15
 */
@Data
public class ProxyChain {
    /**
     * 目标类
     */
    private final Class<?> targetClass;
    /**
     * 目标对象
     */
    private final Object targetObject;
    /**
     * 目标方法
     */
    private final Method targetMethod;
    /**
     * 方法代理
     */
    private final MethodProxy methodProxy;
    /**
     * 方法参数
     */
    private final Object[] methodParams;
    /**
     * 代理索引：充当代理对象的计数器
     */
    private int proxyIndex = 0;
    /**
     * 代理列表
     */
    private List<Proxy> proxyChain;

    public ProxyChain(Class<?> targetClass, Object targetObject, Method targetMethod, MethodProxy methodProxy,
                      Object[] methodParams, List<Proxy> proxyChain) {
        this.targetClass = targetClass;
        this.targetObject = targetObject;
        this.targetMethod = targetMethod;
        this.methodProxy = methodProxy;
        this.methodParams = methodParams;
        this.proxyChain = proxyChain;
    }

    /**
     * 执行代理链
     *
     * @return 执行结果
     * @throws Throwable 异常
     */
    public Object doProxyChain() throws Throwable {
        Object result;
        if (proxyIndex < proxyChain.size()) {
            //执行代理链上的切面方法
            result = proxyChain.get(proxyIndex++).doProxy(this);
        } else {
            //执行原被代理的方法
            result = methodProxy.invokeSuper(targetObject, methodParams);
        }
        return result;
    }
}
